/* 
 * Created on 2008-1-18
 * Last modified on 2008-8-17
 * Powered by YeQiangWei.com
 */
package com.yeqiangwei.commons.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 
 * @author HongGuang
 */
public class DateTimeUtils {

	public static void main(String args[]) throws ParseException {

		Long ctime = new Long("1260324718000");

		System.out.println("/" + ctime.toString().length());

		System.out.println(ctime);
		System.out.println(DateTimeUtils.format(ctime, null));
		System.out.println("===================================");

		long time = DateTimeUtils.now();
		System.out.println(time);
		System.out.println("First day of week: " + DateTimeUtils.format(getFirstDayOfWeek(null), null));
		System.out.println("First day of month: " + DateTimeUtils.format(getFirstDayOfMonth(), null));
		System.out.println("Last day of month: " + DateTimeUtils.format(getLastDayOfMonth(), null));

	}

	/**
	 * 获取N天的秒数
	 * 
	 * @param n
	 * @return
	 */
	public static int getSecondsForNDay(int n) {
		return n * 60 * 60 * 24;
	}

	/**
	 * 设置后几天的几点
	 * 
	 * @param days
	 * @param settime
	 * @return String
	 */
	public static String nDaysAtHourGMT(int days, int hour) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, days);
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, 1);
		calendar.set(Calendar.SECOND, 1);
		int offset = calendar.get(Calendar.ZONE_OFFSET) / 3600000
				+ calendar.get(Calendar.DST_OFFSET) / 3600000;
		calendar.add(Calendar.HOUR, -offset);
		SimpleDateFormat sdf = new SimpleDateFormat(
				"EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
		return sdf.format(calendar.getTime());
	}

	public static String nHoursAfterTimeGMT(int hours) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.HOUR_OF_DAY, hours);
		int offset = calendar.get(Calendar.ZONE_OFFSET) / 3600000
				+ calendar.get(Calendar.DST_OFFSET) / 3600000;
		calendar.add(Calendar.HOUR, -offset);
		SimpleDateFormat sdf = new SimpleDateFormat(
				"EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
		return sdf.format(calendar.getTime());
	}

	public static String nSecondsAfterTimeGMT(int seconds) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.SECOND, seconds);
		int offset = calendar.get(Calendar.ZONE_OFFSET) / 3600000
				+ calendar.get(Calendar.DST_OFFSET) / 3600000;
		calendar.add(Calendar.HOUR, -offset);
		SimpleDateFormat sdf = new SimpleDateFormat(
				"EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
		return sdf.format(calendar.getTime());
	}

	/**
	 * 
	 * @param time
	 * @return String
	 */
	public static String formatToGMT(long time) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date(time));
		int offset = calendar.get(Calendar.ZONE_OFFSET) / 3600000
				+ calendar.get(Calendar.DST_OFFSET) / 3600000;
		calendar.add(Calendar.HOUR, -offset);
		SimpleDateFormat sdf = new SimpleDateFormat(
				"EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
		return sdf.format(calendar.getTime());
	}

	/**
	 * 
	 * @param time
	 * @return String
	 */
	public static String timeToString(long time) {
		return timeToString(time, FMT_YYYY_MM_DD);
	}

	/**
	 * 
	 * @param time
	 * @param fmt
	 * @return String
	 */
	private final static String timeToString(long timeInMillis, String fmt) {
		if (ValidatorHelper.isEmpty(fmt)) {
			fmt = FMT_YYYY_MM_DD;
		}
		String timeToStr = "";
		long s = (now() - timeInMillis) / 1000; // 计算time和当前时间间隔的秒数
		if (s < 0) {
			timeToStr = "刚刚";
		} else if (s < 15) {
			timeToStr = "刚刚";
		} else if (s < 60) {
			timeToStr = s + "秒前";
		} else if (s < 3600) { // 12小时前
			timeToStr += (s / 60) + "分" + (s % 60) + "秒前";
		} else if (s < 43200) { // 12小时前
			timeToStr = TypeChange.doubleToInt(ArithHelper.div(s, 3600, 0))
					+ "小时";
			long m = +(s % 3600);
			timeToStr += (m / 60) + "分";
			timeToStr += (m / 60) + "秒前";
		} else {
			long yyyydd_ = TypeChange.stringToLong(DateTimeUtils.format(
					timeInMillis, "yyyyMMdd")); // 自定义时间
			long yyyydd = TypeChange.stringToLong(DateTimeUtils.format(now(),
					"yyyyMMdd")); // 今天
			if (yyyydd == yyyydd_) {
				timeToStr = "<font style=\"font-size:12px; color:#cc0000;\" class=\"today\">今天</font> ";
				timeToStr += DateTimeUtils.format(timeInMillis, FMT_HH_MM_SS);
			} else if (yyyydd == (yyyydd_ + 1)) {
				timeToStr = "<font style=\"font-size:12px; color:#006600;\" class=\"yestoday\">昨天</font> ";
				timeToStr += DateTimeUtils.format(timeInMillis, FMT_HH_MM_SS);
			} else if (yyyydd == (yyyydd_ + 2)) {
				timeToStr = "<font style=\"font-size:12px; color:#2A00FF;\" class=\"byestoday\">前天</font> ";
				timeToStr += DateTimeUtils.format(timeInMillis, FMT_HH_MM_SS);
			} else {
				int year = DateTimeUtils.getYear(timeInMillis);
				if (year != DateTimeUtils.getCurrentYear()) {
					timeToStr = DateTimeUtils.format(timeInMillis,
							FMT_YYYY_MM_DD);
				} else {
					// HH:mm:ss
					timeToStr = DateTimeUtils.format(timeInMillis,
							FMT_MM_DD_HH_MM);
				}
			}
		}
		return timeToStr;
	}

	public static final String FMT_HH_MM_SS = "HH:mm:ss";
	public static final String FMT_YYYY_MM_DD = "yyyy-MM-dd";
	public static final String FMT_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
	public static final String FMT_MM_DD_HH_MM = "MM-dd HH:mm";
	public static final String FMT_YYYYMM = "yyyyMM";

	/*
	 * 
	 * /
	 * 
	 * @param timeInMillis
	 * 
	 * @param fmt 时间格式，默认：yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String format(long timeInMillis, String fmt) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(timeInMillis);
		if (ValidatorHelper.isEmpty(fmt)) {
			fmt = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat sdf = null;
		try {
			sdf = new SimpleDateFormat(fmt);
		} catch (RuntimeException e) {
			System.out.println(System.err);
			sdf = new SimpleDateFormat();
		}
		return sdf.format(new Date(timeInMillis));
	}

	/**
	 * 格式化到天
	 * 
	 * @param timeInMillis
	 * @return yyyy-MM-dd
	 */
	public static String formatToDay(long timeInMillis) {
		return DateTimeUtils.format(timeInMillis, "yyyy-MM-dd");
	}

	/**
	 * 在当前时间，加(减)n秒以后的时间。
	 * 
	 * @return
	 */
	public static long nSecondsAfterTime(int seconds) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.SECOND, seconds);
		return calendar.getTimeInMillis();
	}

	/**
	 * 在指定时间，加(减)n秒以后的时间。
	 * 
	 * @param timeInMillis
	 *            指定时间
	 * @param seconds
	 *            正(负)秒数
	 * @return
	 */
	public static long nSecondsAfterTime(long timeInMillis, int seconds) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(timeInMillis);
		calendar.add(Calendar.SECOND, seconds);
		return calendar.getTimeInMillis();
	}

	public static long nSecondAfterNow(int i) {
		return nSecondsAfterTime(i);
	}

	/**
	 * 在指定时间，加(减)n小时以后的时间。
	 * 
	 * @param timeInMillis
	 * @param hours
	 * @return long
	 */
	public static long nHoursAfterTime(long timeInMillis, int hours) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(timeInMillis);
		calendar.add(Calendar.HOUR_OF_DAY, hours);
		return calendar.getTimeInMillis();
	}

	/**
	 * 在当前时间，加(减)n天以后的时间。
	 * 
	 * @return
	 */
	public static long nDaysAfterTime(int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, days);
		return calendar.getTimeInMillis();
	}

	/**
	 * 在指定时间，加(减)n天以后的时间。
	 * 
	 * @param timeInMillis
	 *            指定时间
	 * @param seconds
	 *            正(负)秒数
	 * @return
	 */
	public static long nDaysAfterTime(long timeInMillis, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(timeInMillis);
		calendar.add(Calendar.DAY_OF_MONTH, days);
		return calendar.getTimeInMillis();
	}

	/**
	 * 返回到当前年份
	 * 
	 * @return
	 */
	public static int getCurrentDayOfYear() {
		return Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
	}

	/**
	 * @like getCurrentDate()
	 * @return
	 */
	public static int getCurrentDayOfMonth() {
		return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 当前日期
	 * 
	 * @return
	 */
	public static int getCurrentDate() {
		return Calendar.getInstance().get(Calendar.DATE);
	}

	public static int getLastDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month);
		// 某年某月的最后一天
		return cal.getActualMaximum(Calendar.DATE);
	}

	/**
	 * 当前年份
	 * 
	 * @return
	 */
	public static int getCurrentYear() {
		return Calendar.getInstance().get(Calendar.YEAR);
	}

	/**
	 * 当前月份
	 * 
	 * @return
	 */
	public static int getCurrentMonth() {
		return Calendar.getInstance().get(Calendar.MONTH);
	}

	public static int getHourOfDay() {
		return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 指定时间的日期
	 * 
	 * @param timeInMillis
	 * @return
	 */
	public static int getDate(long timeInMillis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(timeInMillis);
		return calendar.get(Calendar.DATE);
	}

	public static Date getDate(int year, int month, int date) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month - 1);
		calendar.set(Calendar.DATE, date);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * @like getDate(long timeInMillis)
	 * @param timeInMillis
	 * @return
	 */
	public static int getDayOfMonth(long timeInMillis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(timeInMillis);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 指定时间的年份
	 * 
	 * @param timeInMillis
	 * @return
	 */
	public static int getYear(long timeInMillis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(timeInMillis);
		return calendar.get(Calendar.YEAR);
	}

	/**
	 * 指定时间的月份
	 * 
	 * @param timeInMillis
	 * @return
	 */
	public static int getMonth(long timeInMillis) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(timeInMillis);
		return calendar.get(Calendar.MONTH);
	}

	public static long now() {
		return new Date().getTime();
	}

	public static long getTimeInMillis() {
		return Calendar.getInstance().getTimeInMillis();
	}

	/**
	 * 
	 * @param year
	 * @param month
	 * @param dayOfMonth
	 * @return long
	 */
	public static long getTimeInMillis(int year, int month, int dayOfMonth) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		return calendar.getTimeInMillis();
	}

	public static long getTimeInMillisForDayBegin(int year, int month,
			int dayOfMonth) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTimeInMillis();
	}

	public static long getTimeInMillisForDayEnd(int year, int month,
			int dayOfMonth) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		return calendar.getTimeInMillis();
	}
	
	/**
	 * 获取本月的第一天
	 * @return
	 */
	public static long getFirstDayOfMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		return calendar.getTimeInMillis();
	}
	
	/**
	 * 获取本月的最后一天
	 * @return
	 */
	public static long getLastDayOfMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, 1);//本月最后一天
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		return calendar.getTimeInMillis();
	}

	/**
	 * 获取本周的第一天的时间
	 * @param offset 偏差 中国习惯以礼拜1作为第一天所以天数偏差为正1
	 * @return
	 */
	public static long getFirstDayOfWeek(Integer offset) {
		Calendar calendar = Calendar.getInstance();
		if(offset != null) {
			calendar.set(Calendar.DAY_OF_WEEK, 1 + offset);
		}
		else {
			calendar.set(Calendar.DAY_OF_WEEK, 1);//本周第一天，以星期日开始
		}
		return calendar.getTimeInMillis();
	}
	
	/**
	 * 获取本周的最后一天的时间
	 * @return
	 */
	public static long getLastDayOfWeek(Integer offset) {
		Calendar calendar = Calendar.getInstance();
		if(offset != null) {
			calendar.set(Calendar.DAY_OF_WEEK, 7 + offset);
		}
		else {
			calendar.set(Calendar.DAY_OF_WEEK, 7);//本周最后一天，以星期日开始
		}
		return calendar.getTimeInMillis();
	}

}
